home *** CD-ROM | disk | FTP | other *** search
/ Aminet 8 / Aminet 8 (1995)(GTI - Schatztruhe)[!][Oct 1995].iso / Aminet / util / cdity / Yak210src.lha / Yak_2.10_Src / handlers.c < prev    next >
C/C++ Source or Header  |  1995-08-19  |  27KB  |  1,047 lines

  1. /*
  2.  * Handlers.c
  3.  *
  4.  * This module contains the input handlers set up by Yak.
  5.  * 
  6.  * The main handler is for autopointing, keyactivation, keyclicking and blanking
  7.  * There's are 3 specialized handlers for mouse cycling functions : WindowToFront,
  8.  * WindowToBack, and ScreenCycling.
  9.  * 
  10.  */
  11.  
  12. #define __USE_SYSBASE
  13.  
  14. #include <exec/types.h>
  15. #include <exec/exec.h>
  16. #include <devices/console.h>
  17. #include <devices/input.h>
  18. #include <devices/inputevent.h>
  19. #include <libraries/commodities.h>
  20. #include <graphics/gfx.h>
  21. #include <graphics/gfxbase.h>
  22. #include <graphics/gfxmacros.h>
  23. #include <graphics/displayinfo.h>
  24. #include <hardware/custom.h>
  25. #include <hardware/dmabits.h>
  26. #include <intuition/intuition.h>
  27. #include <intuition/intuitionbase.h>
  28. #include <proto/exec.h>
  29. #include <proto/dos.h>
  30. #include <proto/layers.h>
  31. #include <proto/graphics.h>
  32. #include <proto/intuition.h>
  33. #include <proto/commodities.h>
  34. #include <ctype.h>
  35. #include <string.h>
  36. #include <stdio.h>
  37.  
  38. #include "code.h"
  39. #include "yak.h"
  40. #include "Settings.h"
  41. #include "Handlers.h"
  42. #include "hotkey_types.h"
  43. #ifdef PREFS
  44. #  define CATCOMP_NUMBERS
  45. #  include "yak_locale_strings.h"
  46. #  include "Requesters.h"
  47. #else
  48. #  ifndef CONV
  49. #    include "Beep.h"
  50. #    include "LastActiveWindow.h"
  51. #  endif
  52. #endif
  53.  
  54.  
  55. static char ExcludeWbWindowPattern[20]; /* Normally it takes 13 bytes */
  56.  
  57.  
  58. YakHandler MouseCyclingHandlers[NUM_HANDLERS] = {
  59.    { NULL, NULL, 0, 0, 0, 0, NULL, "", NULL},
  60.    { NULL, NULL, 0, 0, 0, 0, NULL, "", NULL},
  61.    { NULL, NULL, 0, 0, 0, 0, NULL, "", NULL}
  62. };
  63.  
  64. YakHandler DEF_MOUSECYCLING[NUM_HANDLERS]= {
  65.    { NULL, WindowToFrontHandler, YKHK_INACTIVE, WINDOW_TOFRONT_EVENT, DEF_TOFRONT_CLICKS      , DEF_TOFRONT_OPTIONS      , DEF_TOFRONT_HOTKEY      , DEF_SCREENPATTERN },
  66.    { NULL, WindowToBackHandler , YKHK_INACTIVE, WINDOW_TOBACK_EVENT,  DEF_TOBACK_CLICKS       , DEF_TOBACK_OPTIONS       , DEF_TOBACK_HOTKEY       , DEF_SCREENPATTERN },
  67.    { NULL, ScreenCyclingHandler, YKHK_INACTIVE, SCREENCYCLING_EVENT,  DEF_SCREENCYCLING_CLICKS, DEF_SCREENCYCLING_OPTIONS, DEF_SCREENCYCLING_HOTKEY, DEF_SCREENPATTERN }
  68. };
  69.  
  70.  
  71. VOID
  72. CleanMouseCycling(void)
  73. {
  74.     register int i;
  75.     
  76.     for (i=0; i<NUM_HANDLERS; i++)
  77.     {
  78.         if (MouseCyclingHandlers[i].ScreenPatternData.pat)
  79.         { 
  80.             FreeVec(MouseCyclingHandlers[i].ScreenPatternData.pat);
  81.             MouseCyclingHandlers[i].ScreenPatternData.pat=NULL;
  82.         }
  83.  
  84.         if (MouseCyclingHandlers[i].KeyDef)
  85.         { 
  86.             FreeVec(MouseCyclingHandlers[i].KeyDef);
  87.             MouseCyclingHandlers[i].KeyDef=NULL;
  88.         }
  89.  
  90.         /* DeleteCxObjAll() works even with NULL argument */
  91.         DeleteCxObjAll(MouseCyclingHandlers[i].CxObj);    
  92.         MouseCyclingHandlers[i].CxObj=NULL;
  93.     }
  94. }
  95.  
  96.  
  97.  
  98. VOID
  99. InitMouseCyclingPatterns (VOID)
  100. {
  101.     UBYTE i;
  102.  
  103.     for (i=0; i<NUM_HANDLERS; i++)
  104.     {
  105.         InitPattern(MouseCyclingHandlers[i].ScreenPatternData.patstr,
  106.                     &MouseCyclingHandlers[i].ScreenPatternData);
  107.     }
  108.  
  109. #if !defined(PREFS) && !defined(CONV)
  110.     /* Initialize the pattern to exclude Wb window for Window_To_Front */
  111.     ParsePattern("~(Workbench)", ExcludeWbWindowPattern, 20);
  112. #endif    
  113. }
  114.  
  115.  
  116. /*
  117.  *  CompatibleParseIX - frontend to ParseIX() to allow compatibility of V38+ 
  118.  *  commodity.library hotkey definitions with V37 library.
  119.  */
  120.  
  121. long 
  122. CompatibleParseIX(char *I_Description, IX *ix)
  123. {
  124.     char *pos=NULL;
  125.     UBYTE c, begin;
  126.     long failurecode = 0l;
  127.     UWORD code = 0;
  128.     char *description;
  129.  
  130.     if (I_Description == NULL)
  131.     {
  132.         failurecode = -2;
  133.     }
  134.     else
  135.     {
  136.         /* Skip blank spaces in a 68000 compatible way, avoid odd addresses */
  137.  
  138.         begin = 0;
  139.         while (I_Description[begin] == ' ') 
  140.         {
  141.             begin++;
  142.         }
  143.  
  144.         if (CxBase->lib_Version < 38L) /* COMMODITIES_V37 */
  145.         {
  146.             description = AllocVec(strlen(I_Description)+1-begin, MEMF_CLEAR);
  147.  
  148.             for (c=begin; c<strlen(I_Description); c++)
  149.                 description[c-begin] = tolower(I_Description[c]);
  150.  
  151.             /*
  152.              *  parse and remove keywords that are not supported
  153.              *  by V37 commodities.library
  154.              *
  155.              */
  156.             if (pos = strstr(description, " mouse_leftpress"))
  157.             {
  158.                 code = IECODE_LBUTTON;
  159.             }
  160.             else 
  161.             {
  162.                 if (pos = strstr(description, " mouse_rightpress"))
  163.                 {
  164.                     code = IECODE_RBUTTON;
  165.                 }
  166.                 else 
  167.                 {
  168.                     if (pos = strstr(description, " mouse_middlepress"))
  169.                     {
  170.                         code = IECODE_MBUTTON;
  171.                     }
  172.                 }
  173.             }
  174.  
  175.             if (pos)            /* RawMouse class */
  176.             {
  177.                 /* Put an end to our description before unsupported keywords
  178.                  * but avoid odd address for 68000 
  179.                  */
  180.                 description[(LONG)pos - (LONG)description]= '\0';
  181.             }
  182.  
  183.             failurecode = ParseIX((UBYTE *)description, ix);
  184.  
  185.             /*
  186.              *  now change ix for our new keywords
  187.              *
  188.              */
  189.             if (code) 
  190.             {
  191.                 /*
  192.                  *  change code
  193.                  *
  194.                  */
  195.                 if (ix->ix_Class != IECLASS_RAWMOUSE)
  196.                     failurecode = -1;
  197.                 else
  198.                     ix->ix_Code = code;
  199.             
  200.                 /*
  201.                  *  change also QualMask for mouse buttons
  202.                  *
  203.                  */
  204.                 ix->ix_QualMask |= IEQUALIFIER_MIDBUTTON | IEQUALIFIER_RBUTTON | IEQUALIFIER_LEFTBUTTON;
  205.  
  206.                 /*
  207.                  *  parse for qualifiers the use wants to be considered irrelevant
  208.                  *
  209.                  */
  210.                 if (strstr(description, "-leftbutton")) ix->ix_QualMask &= ~IEQUALIFIER_LEFTBUTTON;
  211.                 if (strstr(description, "-midbutton")) ix->ix_QualMask &= ~IEQUALIFIER_MIDBUTTON;
  212.                 if (strstr(description, "-rbutton")) ix->ix_QualMask &= ~IEQUALIFIER_RBUTTON;
  213.  
  214.             }
  215.  
  216.             FreeVec(description);
  217.         }
  218.         else                    /* COMMODITIES_V38+ */
  219.         {
  220.             /* Use the definition as is */
  221.             failurecode = ParseIX((UBYTE *)I_Description, ix);
  222.         }
  223.  
  224.         if (!failurecode)
  225.         {
  226.             /* Patch ParseIX() up */
  227.             if (ix->ix_Class == IECLASS_RAWMOUSE)
  228.             {
  229.                 if (ix->ix_Code == IECODE_LBUTTON) ix->ix_Qualifier |= IEQUALIFIER_LEFTBUTTON;
  230.                 if (ix->ix_Code == IECODE_MBUTTON) ix->ix_Qualifier |= IEQUALIFIER_MIDBUTTON;
  231.                 if (ix->ix_Code == IECODE_RBUTTON) ix->ix_Qualifier |= IEQUALIFIER_RBUTTON;
  232.             }
  233.             ix->ix_QualMask |= ix->ix_Qualifier;
  234.         }
  235.     }
  236.     return(failurecode);
  237. }
  238.  
  239. #if !defined(PREFS) && !defined(CONV)
  240.  
  241. void TurnMouseOn (void);
  242. static void TurnMouseOff (void);
  243. static __regargs void IntuiOp (void (*routine) (APTR), APTR parameter);
  244. static __regargs void PopToFront (struct Window *win);
  245. static __regargs BOOL StrGadgetActive (struct Window *w);
  246.  
  247. extern __far struct Custom custom;
  248.  
  249. #define REBLANKCOUNT    10      /* how long to wait to reblank mouse */
  250. #define TURN_OFF_SPRITES {OFF_SPRITE;custom.spr[0].dataa = custom.spr[0].datab = 0;}
  251.  
  252. void (*intui_routine) (APTR);   /* for intui_op's */
  253. APTR intui_parameter;
  254. CxObj *clickobj;
  255. ULONG clicksigflag, intuiopsigflag, blankscreensigflag, depthscreensigflag;
  256. static BYTE clicksigbit, blankscreensigbit, depthscreensigbit, intuiopsigbit = -1;
  257. static BOOL misspop;
  258.  
  259. /* for screen cycling */
  260. STACKARGS void
  261. MyScreenToBack (struct Screen *scr)
  262. {
  263.   RememberActiveWindow(NULL);
  264.   ScreenToBack (scr);
  265.   ActivateMouseWindow (SCREEN);
  266. }
  267.  
  268. STACKARGS void
  269. MyScreenToFront (struct Screen *scr)
  270. {
  271.   RememberActiveWindow(NULL);
  272.   ScreenToFront (scr);
  273.   ActivateMouseWindow (SCREEN);
  274. }
  275.  
  276.  
  277. /* Stub for Intuition routines - passes request on to main task.
  278.  * DO NOT CALL WHILE FORBID()ING!
  279.  * Thanks to Eddy Carroll for this.
  280.  */
  281.  
  282. #define WTB(win)        IntuiOp(WindowToBack, win)
  283. #define WTF(win)        IntuiOp(WindowToFront, win)
  284. #define WACT(win)       IntuiOp((void (*)(APTR))ActivateWindow, win)
  285. #define STB(scr)        IntuiOp(MyScreenToBack, scr)
  286. #define STF(scr)        IntuiOp(MyScreenToFront, scr)
  287.  
  288. BYTE oldpri;                  /* used by main.c */
  289. static struct Task *YakTask;  
  290.  
  291. static __regargs void
  292. IntuiOp (void (*routine) (APTR), APTR parameter)
  293. {
  294.   oldpri  = SetTaskPri (YakTask, 21);
  295.   intui_routine = routine;
  296.   intui_parameter = parameter;
  297.   Signal (YakTask, intuiopsigflag);
  298. }
  299.  
  300. /* pattern-matching on screen/window titles */
  301. #define IsXXXScreen(scr, pat)          (scr && (!scr->DefaultTitle || MatchPattern(pat, scr->DefaultTitle)))
  302. #define IsAutoScreen(scr)              IsXXXScreen(scr, autoscrpat)
  303. #define IsXXXWindow(win, pat)          (!win->Title || MatchPattern(pat, win->Title))
  304. #define IsPopWindow(win)               IsXXXWindow(win,popwinpat)
  305. #define IsNotWbWindow(win)             (!win->Title || MatchPattern(ExcludeWbWindowPattern, win->Title))
  306. #define IsIncludedScreen(scr,handler)  IsXXXScreen(scr, handler.ScreenPatternData.pat) 
  307.  
  308. /* when is a window safe to bring to front and not already at front? */
  309. #define OkayToPop(win)  (!win->ReqCount && !(win->Flags & (WFLG_MENUSTATE|WFLG_BACKDROP)) \
  310.                          && win->WLayer->ClipRect && win->WLayer->ClipRect->Next)
  311.  
  312.  
  313.  
  314. /* WindowToFront only if no requester, not backdrop, not already front... */
  315. static __regargs void
  316. PopToFront (struct Window *win)
  317. {
  318.     /* want to avoid popping immediately after mousebutton/keyboard */
  319.     if (misspop)
  320.     {
  321.         misspop = FALSE;
  322.     }
  323.     else
  324.     { 
  325.         if (OkayToPop (win))
  326.         {
  327.             /* Does it pass pattern? */
  328.             if (IsPopWindow (win))
  329.             {
  330.                 WTF (win); /* We use signals to reduce time spent in the input device */
  331.             }
  332.         }
  333.     }
  334. }
  335.  
  336. /* modified from DMouse */
  337. /* expects multitasking to be Forbid()en */
  338.  
  339. static struct Screen *mousescr; /* the screen under the mouse */
  340.  
  341.  
  342. struct Screen *
  343. ScreenUnderMouse( void )
  344. {
  345.   struct Screen *scr;
  346.   ULONG lock;
  347.  
  348.   lock = LockIBase(0);
  349.         
  350.   for (scr = IntuitionBase->FirstScreen;
  351.            scr && scr->TopEdge > 0 && scr->MouseY < 0; 
  352.            scr = scr->NextScreen);
  353.  
  354.   UnlockIBase(lock);
  355.  
  356.   return(scr);
  357. }
  358.  
  359.  
  360. struct Window *
  361. WindowUnderMouse( void )
  362. {
  363.   struct Layer *layer = NULL;
  364.   ULONG lock;
  365.  
  366.   lock = LockIBase(0);
  367.         
  368.   for (mousescr = IntuitionBase->FirstScreen;
  369.            mousescr && mousescr->TopEdge > 0 && mousescr->MouseY < 0; 
  370.            mousescr = mousescr->NextScreen);
  371.  
  372.   UnlockIBase(lock);
  373.  
  374.   if (mousescr)
  375.           layer = WhichLayer(&mousescr->LayerInfo, mousescr->MouseX, mousescr->MouseY);
  376.       
  377.   return (layer ? (struct Window *) layer->Window : NULL);
  378. }
  379.  
  380.  
  381. /* does active window have an active string gadget? */
  382. static __regargs BOOL
  383. StrGadgetActive (struct Window *w)
  384. {
  385.   struct Gadget *g = w->FirstGadget;
  386.  
  387.   for (; g; g = g->NextGadget)
  388.     if ((g->GadgetType & STRGADGET) && (g->Flags & GFLG_SELECTED))
  389.       return TRUE;
  390.   return FALSE;
  391. }
  392.  
  393. /* activate window under mouse */
  394. /* context sensitive; why tells routine how to behave */
  395. /* can be AUTO, KEY, SCREEN, RMBACT */
  396. __regargs void
  397. ActivateMouseWindow (BYTE why)
  398. {
  399.     struct Window *win = NULL, *IB_ActiveWindow;
  400.     ULONG lock;
  401.  
  402.     if ((why != SCREEN) || scractivate)
  403.     {
  404.         if (why == SCREEN)
  405.         {
  406.             win = LastActiveWindow(ScreenUnderMouse());
  407.         }
  408.  
  409.         if (!win)
  410.             win = WindowUnderMouse ();
  411.  
  412.         if (win)                /* window exists to activate */
  413.         {
  414.             /* either window is not active or auto-activating - need to pop? */
  415.           
  416.             if (win->Flags & WFLG_WINDOWACTIVE) /* already active - needs popped? */
  417.             {
  418.                 if (why == AUTO && autopop && IsAutoScreen (win->WScreen))
  419.                 {
  420.                     PopToFront (win);
  421.                 }
  422.             }
  423.             else if (why != AUTO || IsAutoScreen (win->WScreen))
  424.             {
  425.                 /* window is not active, should we try to activate it? */
  426.                   
  427.                 lock = LockIBase(0);
  428.                 IB_ActiveWindow = IntuitionBase->ActiveWindow;
  429.                 UnlockIBase(lock);
  430.  
  431.                 if (!IB_ActiveWindow ||
  432.                     !(IB_ActiveWindow->Flags & WFLG_MENUSTATE) && /* not showing menus */
  433.                     !(why == KEY && StrGadgetActive (IB_ActiveWindow))) /* no str gad active */
  434.                 {
  435.                           
  436.                     /* do autopop? */
  437.                     if (why == AUTO && autopop)
  438.                         PopToFront (win);
  439.                           
  440.                     if (why == KEY)
  441.                         ActivateWindow (win); /* need this to avoid losing keys */
  442.                     else
  443.                         WACT (win); /* ...activate window */
  444.  
  445.                     RememberActiveWindow(win);
  446.  
  447.                 }
  448.             }
  449.         }
  450.         else
  451.         {
  452.             lock = LockIBase(0);
  453.             IB_ActiveWindow = IntuitionBase->ActiveWindow; 
  454.             UnlockIBase(lock);
  455.  
  456.             if (scractivate && mousescr && mousescr->FirstWindow &&
  457.                 ((why == SCREEN) || 
  458.                  (why == RMBACT && IB_ActiveWindow && IB_ActiveWindow->WScreen != mousescr)))
  459.             {
  460.                 WACT (mousescr->FirstWindow); /* ...activate window */
  461.                 RememberActiveWindow(mousescr->FirstWindow);
  462.             }
  463.         }
  464.     }
  465. }
  466.  
  467. static __chip UWORD posctldata[4];
  468. static struct SimpleSprite simplesprite =
  469. {posctldata, 0, 0, 0, 0};
  470. static BOOL mouseoff;           /* is mouse off? (MB_SPRITES only) */
  471.  
  472. void 
  473. TurnMouseOn ()                  /* restore mouse-pointer */
  474. {
  475.     if (mouseblank == MB_SPRITES) /* really dirty blanking */
  476.     {                           /* but guaranteed to work... */
  477.         if (mouseoff)
  478.         {
  479.             Forbid ();
  480.             WaitTOF ();
  481.             ON_SPRITE;
  482.             Permit ();
  483.         }
  484.     }
  485.     else
  486.     {
  487.         RethinkDisplay();
  488.     }
  489.     mouseoff = FALSE;
  490. }
  491.  
  492. static void 
  493. TurnMouseOff ()                 /* blank mouse-pointer */
  494. {
  495.     if (!mouseoff)              /* no point in turning it off twice... */
  496.     {
  497.         Forbid ();
  498.  
  499.         if (mouseblank == MB_SPRITES)
  500.         {
  501.             WaitTOF ();
  502.             OFF_SPRITE;
  503.             custom.spr[0].dataa = custom.spr[0].datab = 0;          
  504.         }
  505.         else
  506.         {
  507.             ChangeSprite(NULL, &simplesprite, (APTR)posctldata);
  508.         }
  509.  
  510.         Permit ();
  511.  
  512.         mouseoff = TRUE;
  513.     }
  514. }
  515.  
  516. BOOL blanked;
  517. static struct Screen *blankscr;
  518.  
  519. void
  520. BlankScreen ()
  521. {
  522.     if (screenblank == SB_DMA)
  523.     {
  524.         /* Turn DMA off */
  525.         custom.dmacon = BITCLR|DMAF_RASTER|DMAF_COPPER|DMAF_SPRITE;  
  526.  
  527.         blanked = TRUE;
  528.     }
  529.     else
  530.     {
  531.         ULONG modeid = INVALID_ID;
  532.         
  533.         if (blankscr)
  534.             ScreenToFront (blankscr);
  535.         else
  536.         {
  537.             Forbid ();
  538.             if (IntuitionBase->FirstScreen)
  539.                 modeid = GetVPModeID (&(IntuitionBase->FirstScreen->ViewPort));
  540.             Permit ();
  541.             if (modeid == INVALID_ID)
  542.                 modeid = LORES_KEY;
  543.                 
  544.             if (blankscr = OpenScreenTags (NULL, SA_Depth, 1,
  545.                                            SA_Title, "Yak blanking screen",
  546.                                            SA_Quiet, TRUE,
  547.                                            SA_Behind, TRUE,
  548.                                            SA_DisplayID, modeid,
  549.                                            TAG_DONE))
  550.             {
  551.                 SetRGB4 (&blankscr->ViewPort, 0, 0, 0, 0);
  552.                 ScreenToFront (blankscr);
  553.                 blanked = TRUE;
  554.             }
  555.         }
  556.         /* Blank all the sprites */
  557.         TURN_OFF_SPRITES; 
  558.     }
  559.  
  560.     /* Blank mouse in case OFF_SPRITE or DMA off didn't work (case of PICASSO II board) */
  561.     TurnMouseOff();
  562. }
  563.  
  564. void
  565. UnBlankScreen ()
  566. {
  567.     if (screenblank == SB_DMA)
  568.     {
  569.         /* Turn DMA on */
  570.         custom.dmacon = BITSET|DMAF_RASTER|DMAF_COPPER|DMAF_SPRITE;
  571.     }
  572.     else
  573.     {
  574.         if (blankscr)
  575.             CloseScreen (blankscr);
  576.         blankscr = NULL;
  577.         blanked = FALSE;
  578.         ON_SPRITE;
  579.     }
  580.     /* UnBlank mouse in case ON_SPRITE or DMA on didn't work (case of PICASSO II board) */
  581.     TurnMouseOn();
  582. }
  583.  
  584. #define ALL_BUTTONS     (IEQUALIFIER_LEFTBUTTON|IEQUALIFIER_RBUTTON|IEQUALIFIER_MIDBUTTON)
  585. #define KEY_QUAL        (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT \
  586.                         |IEQUALIFIER_CONTROL \
  587.                         |IEQUALIFIER_LALT|IEQUALIFIER_RALT \
  588.                         |IEQUALIFIER_LCOMMAND|IEQUALIFIER_RCOMMAND)
  589. #define ALL_QUALS       (ALL_BUTTONS|KEY_QUAL)
  590.  
  591.  
  592. /*
  593.  * MainHandler is an input handler with no filter attached, it sees everything
  594.  * and so can manage keyactivation, autopointing, keyclicking and blanking
  595.  */
  596.  
  597.  
  598. SAVEDS void
  599. MainHandler (CxMsg * CxMsg, CxObj * CO)
  600. {
  601.     static WORD apcount;        /* timer events since last mousemove */
  602.     struct InputEvent *ev;
  603.              
  604.     ev = (struct InputEvent *) CxMsgData (CxMsg);
  605.     
  606.     switch (ev->ie_Class)
  607.     {
  608.       case IECLASS_TIMER:        /*** AUTO-ACTIVATE/POP, SCREENBLANK, MOUSEBLANK ***/
  609.  
  610.         if (!(ev->ie_Qualifier & ALL_QUALS) && autopoint && !apcount--)
  611.         {
  612.             ActivateMouseWindow (AUTO);
  613.         }
  614.                 
  615.         if (screenblank && !--blankcount) /* blank screen? */
  616.         {
  617.             /* Don't blank screen while we are still in the input.device processing */
  618.             /* Take care of screen mode promotors that open requesters */
  619.             Signal (YakTask, blankscreensigflag);
  620.             blankcount = blanktimeout; /* reset counter */
  621.         }                       /* in case screen opens on top */
  622.                 
  623.         if (mouseblank && !--mblankcount) /* blank mouse? */
  624.         {
  625.             mouseoff = FALSE;   /* force reblank */
  626.             TurnMouseOff ();
  627.             /* in case someone else turns it on, reset counter */
  628.             mblankcount = REBLANKCOUNT;
  629.         }
  630.         break;
  631.  
  632.       case IECLASS_RAWKEY:
  633.         if (!(ev->ie_Code & IECODE_UP_PREFIX))
  634.         {
  635.             /*** MOUSEBLANK, KEYACTIVATE, KEYCLICK ***/
  636.                         
  637.             blankcount = blanktimeout; /* reset blanking countdown */
  638.             if (blanked) /* turn off screen-blanking */
  639.                 UnBlankScreen ();
  640.                         
  641.             if (mouseblank)
  642.             {
  643.                 if (ev->ie_Qualifier & (IEQUALIFIER_LCOMMAND | IEQUALIFIER_RCOMMAND))
  644.                 {
  645.                     /* this allows use of keyboard to move mouse and to access menus */
  646.                     mblankcount = mblanktimeout;
  647.                     TurnMouseOn ();
  648.                 }
  649.                 else
  650.                 {
  651.                     if (blankmouseonkey)
  652.                     {
  653.                         TurnMouseOff (); /* blank the mouse */
  654.                     }
  655.                 }
  656.             }
  657.             if (click_volume && !(ev->ie_Qualifier & IEQUALIFIER_REPEAT))
  658.                 Signal (YakTask, clicksigflag);
  659.                         
  660.         if (!(ev->ie_Qualifier & ALL_BUTTONS) && keyactivate) /* perform key-activate */
  661.                 ActivateMouseWindow (KEY);
  662.         }
  663.         break;
  664.  
  665.       case IECLASS_RAWMOUSE:
  666.         /* restore screen/mouse pointer */
  667.         blankcount = blanktimeout; /* reset blanking countdowns */
  668.         mblankcount = mblanktimeout;
  669.  
  670.         if (blanked) /* turn off screen-blanking */
  671.             UnBlankScreen ();
  672.         if (mouseoff)
  673.             TurnMouseOn ();     /* not needed for MB_COPPER */
  674.                         
  675.         /* maybe should check for depth gadgets? nah... */
  676.         if (!(ev->ie_Qualifier & KEY_QUAL))
  677.         {
  678.             if (!(ev->ie_Qualifier & ALL_BUTTONS))
  679.             {
  680.                 apcount = autopoint_delay; /* reset auto-activate count */
  681.             }
  682.             else
  683.             {
  684.                 misspop = TRUE;
  685.                 apcount = -1;    /* button - wait for move */
  686.  
  687.                 if ((rmbactivate && (ev->ie_Code == IECODE_RBUTTON)) || 
  688.                     (mmbactivate && (ev->ie_Code == IECODE_MBUTTON)))
  689.                 {
  690.                     ActivateMouseWindow (RMBACT);
  691.                 }
  692.  
  693.                 if (ev->ie_Code == IECODE_LBUTTON)
  694.                 {
  695.                     struct Window *win = WindowUnderMouse();
  696.                     if (win == NULL)
  697.                     {
  698.                         /* Check for screen depth gadget */
  699.  
  700.                         struct Screen *screen = ScreenUnderMouse();
  701.                         struct Gadget *ScreenGadget = screen->FirstGadget;
  702.                         struct Gadget *DepthGadget = NULL;
  703.  
  704.                         while (ScreenGadget != NULL)
  705.                         {
  706.                             if ((ScreenGadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_SDEPTH)
  707.                             {
  708.                                 /* We found the screen depth gadget */
  709.                                 DepthGadget = ScreenGadget;
  710.                             }
  711.                             ScreenGadget = ScreenGadget->NextGadget;
  712.                         }
  713.     
  714.                         if ((DepthGadget != NULL) &&
  715.                             (screen->MouseY < DepthGadget->Height) &&
  716.                             (screen->MouseX > (screen->Width - DepthGadget->Width)))
  717.                         {
  718.                             /* Discard event, we'll do the processing ourselves */
  719.                             ev->ie_Class = IECLASS_NULL;
  720.  
  721.                             /* Call main task to process it */
  722.                             Signal (YakTask, depthscreensigflag);
  723.                         }
  724.                     }
  725.                     else
  726.                     {
  727.                         /* A new window will get activated, so remember it 
  728.                          * only if it is a non backdrop window
  729.                          */
  730.                         if (!(win->Flags & WFLG_BACKDROP))
  731.                         {
  732.                             RememberActiveWindow(win);
  733.                         }
  734.                     }
  735.                 }
  736.             }
  737.             
  738.         }
  739.         break;
  740.  
  741.       case IECLASS_DISKINSERTED:
  742.         blankcount = blanktimeout; /* reset blanking countdown */
  743.         if (blanked) /* turn off screen-blanking */
  744.             UnBlankScreen ();
  745.         break;
  746.  
  747.     }
  748. }
  749.  
  750.  
  751.  
  752. IMPORT ULONG secs, micros;
  753. IMPORT UBYTE FRONT_DELAY, BACK_DELAY;
  754.  
  755. void
  756. WindowToFrontHandler (void)
  757. {
  758.     struct Window *win; 
  759.     static ULONG lastfrontmicros = 0l;
  760.     static ULONG lastfrontsecs = 0l;
  761.     static UBYTE frontclicks = 0;
  762.  
  763.     if (Window_To_Front.RequiredClicks >1)
  764.     {
  765.         if (DoubleClick(lastfrontsecs, lastfrontmicros, secs, micros))
  766.         {
  767.             frontclicks++;
  768.         }
  769.         else
  770.         {
  771.             frontclicks = 1;
  772.         }
  773.         lastfrontmicros = micros;
  774.         lastfrontsecs =  secs;
  775.     }
  776.     else
  777.     {
  778.         frontclicks = 1;
  779.     }
  780.  
  781.     if (frontclicks == Window_To_Front.RequiredClicks) 
  782.     {
  783.         if (win = WindowUnderMouse())
  784.         { 
  785.            mousescr = win->WScreen;
  786.  
  787.             if (IsIncludedScreen (mousescr, Window_To_Front))
  788.             {
  789.                 if (OkayToPop (win) && 
  790.                     (!(Window_To_Front.Options & Opt_ExcludeWbWindow) || IsNotWbWindow (win)))
  791.  
  792.                 {
  793.                     if (win->Flags & WFLG_WBENCHWINDOW)
  794.                     { 
  795.                         /* Let some time for wb processing, otherwise 
  796.                          * there will be a big delay of 1 second or so
  797.                          */
  798.                         Delay(FRONT_DELAY); 
  799.                     }
  800.                     WindowToFront (win); 
  801.                 }
  802.                 else 
  803.                 {
  804.                     if (Window_To_Front.Options & Opt_ScreenToFront)
  805.                     {   
  806.                         ScreenToFront (mousescr);
  807.                         ActivateMouseWindow (SCREEN);
  808.                      }
  809.                 }
  810.             }
  811.         }
  812.         else 
  813.         {
  814.             mousescr = ScreenUnderMouse();
  815.             if ((IsIncludedScreen ( mousescr, Window_To_Front )) && 
  816.                 (Window_To_Front.Options & Opt_ScreenToFront))
  817.             {
  818.                 MyScreenToFront(mousescr);
  819.             }
  820.         }
  821.  
  822.         frontclicks = 0;
  823.     }
  824. }
  825.  
  826.  
  827. void
  828. WindowToBackHandler (void)
  829. {
  830.     struct Window *win; 
  831.     static ULONG lastbackmicros = 0l;
  832.     static ULONG lastbacksecs = 0l;
  833.     static UBYTE backclicks = 0;
  834.  
  835.     if (Window_To_Back.RequiredClicks >1)
  836.     {
  837.         if (DoubleClick(lastbacksecs, lastbackmicros, secs, micros))
  838.         {
  839.             backclicks++;
  840.         }
  841.         else
  842.         {
  843.             backclicks = 1;
  844.         }
  845.         lastbackmicros = micros;
  846.         lastbacksecs =  secs;
  847.     }
  848.     else
  849.     {
  850.         backclicks = 1;
  851.     }
  852.  
  853.     if (backclicks == Window_To_Back.RequiredClicks) 
  854.     {
  855.         if (win = WindowUnderMouse())
  856.         {
  857.             mousescr = win->WScreen;
  858.             if (IsIncludedScreen ( mousescr, Window_To_Back ))
  859.             {
  860.                 if (!(win->Flags & WFLG_BACKDROP) && 
  861.                     (win->NextWindow || (win->WScreen->FirstWindow != win)))
  862.                 {
  863.                     if (win->Flags & WFLG_WBENCHWINDOW)
  864.                     { 
  865.                         /* Let some time for wb processing, otherwise 
  866.                          * there will be a big delay of 1 second or so
  867.                          */
  868.                         Delay(BACK_DELAY); 
  869.                     }
  870.                     WindowToBack(win); 
  871.                 }
  872.                 else 
  873.                 {
  874.                     if (Window_To_Back.Options & Opt_ScreenToBack)
  875.                     {
  876.                         ScreenToBack (mousescr);
  877.                         ActivateMouseWindow (SCREEN);
  878.                     }
  879.                 }
  880.             }       
  881.         }
  882.         else 
  883.         {
  884.             mousescr = ScreenUnderMouse();
  885.             if ((IsIncludedScreen ( mousescr, Window_To_Back )) &&
  886.                 (Window_To_Back.Options & Opt_ScreenToBack))
  887.             {
  888.                 MyScreenToBack(mousescr);
  889.             }
  890.         }
  891.         backclicks = 0;
  892.     }
  893. }
  894.  
  895. void
  896. ScreenCyclingHandler (void)
  897. {
  898.     static ULONG lastcyclingmicros = 0l;
  899.     static ULONG lastcyclingsecs = 0l;
  900.     static UBYTE cyclingclicks = 0;
  901.  
  902.     if (ScreenCycling.RequiredClicks >1)
  903.     {
  904.         if (DoubleClick(lastcyclingsecs, lastcyclingmicros, secs, micros))
  905.         {
  906.             cyclingclicks++;
  907.         }
  908.         else
  909.         {
  910.             cyclingclicks = 1;
  911.         }
  912.         lastcyclingmicros = micros;
  913.         lastcyclingsecs =  secs;
  914.     }
  915.     else
  916.     {
  917.         cyclingclicks = 1;
  918.     }
  919.  
  920.     if (cyclingclicks == ScreenCycling.RequiredClicks) 
  921.     {
  922.         mousescr = ScreenUnderMouse();
  923.         if (IsIncludedScreen ( mousescr, ScreenCycling ))
  924.         {
  925.             /* ev->ie_Class = IECLASS_NULL; */
  926.             MyScreenToBack (mousescr);
  927.         }
  928.         cyclingclicks = 0;
  929.     }
  930. }
  931.  
  932.  
  933.  
  934. /* close resources allocated for MainHandler */
  935. void
  936. EndMainHandler ()
  937. {
  938.     /* DeleteCxObjAll works even with CxObj is NULL */
  939.  
  940.     DeleteCxObjAll(clickobj);    
  941.  
  942.     FreeAudio ();
  943.     if (intuiopsigbit != -1)
  944.         FreeSignal (intuiopsigbit);
  945.     if (clicksigbit != -1)
  946.         FreeSignal (clicksigbit);
  947.     if (depthscreensigbit != -1)
  948.         FreeSignal (depthscreensigbit);
  949.     if (blankscreensigbit != -1)
  950.         FreeSignal (blankscreensigbit);
  951.     UnBlankScreen ();
  952. }
  953.  
  954.  
  955. /* open resources needed for MainHandler */
  956. BOOL
  957. InitMainHandler ()
  958. {
  959.     if (((clicksigbit = AllocSignal (-1)) != -1) &&
  960.         ((intuiopsigbit = AllocSignal (-1)) != -1) &&
  961.         ((blankscreensigbit = AllocSignal (-1)) != -1) &&
  962.         ((depthscreensigbit = AllocSignal (-1)) != -1) &&
  963.         AllocAudio ())
  964.     {
  965.         YakTask = FindTask(NULL);
  966.  
  967.         clicksigflag       = 1 << clicksigbit;
  968.         intuiopsigflag     = 1 << intuiopsigbit;
  969.         blankscreensigflag = 1 << blankscreensigbit;
  970.         depthscreensigflag = 1 << depthscreensigbit;
  971.  
  972.         clickobj = CxCustom (MainHandler, 0L);
  973.         AttachCxObj (broker, clickobj);
  974.         
  975.         return TRUE;
  976.     }
  977.     EndMainHandler ();
  978.     return FALSE;
  979. }
  980.  
  981.  
  982. #endif
  983.  
  984.  
  985. #if !defined(CONV)
  986.  
  987. /* open/close resources needed for one of the MouseCycling handlers */
  988.  
  989. static VOID
  990. ToggleYakHandler (YakHandler *YH)
  991. {
  992.     static IX tmpIX = {IX_VERSION,0, 0, 0, 0, 0, 0 }; /* declaring it as static saves some
  993.                                                        * bytes for the intitalization code 
  994.                                                        */
  995.  
  996.     /* DeleteCxObjAll() works even with NULL argument */
  997.     DeleteCxObjAll(YH->CxObj);    
  998.     YH->CxObj=NULL;
  999.         
  1000.     if (YH->State == YKHK_ACTIVE) 
  1001.     {
  1002. #ifdef PREFS
  1003.         if ((YH->CxObj = CxFilter(NULL)) && !CompatibleParseIX(YH->KeyDef, &tmpIX))
  1004.         {
  1005.             /* For prefs we don't want to really set up a filter */
  1006.             DeleteCxObj(YH->CxObj); 
  1007.             YH->CxObj=NULL;
  1008.         }
  1009.         else 
  1010.             PostError("%s:\n\"%s\"", getString(Invalid_hotkey_specif_ERR), YH->KeyDef);
  1011. #else
  1012.         if ((YH->CxObj = CxFilter(NULL)) && !CompatibleParseIX(YH->KeyDef, &tmpIX))
  1013.         {
  1014.             CxObj *tmp_obj;
  1015.  
  1016.             SetFilterIX(YH->CxObj, &tmpIX);
  1017.             AttachCxObj(broker, YH->CxObj);
  1018.         
  1019.             if (tmp_obj = CxSender(broker_mp, YH->Event))
  1020.             {
  1021.                 AttachCxObj(YH->CxObj, tmp_obj);
  1022.                 if ((tmp_obj=CxTranslate(NULL)) && (tmpIX.ix_Code == IECODE_RBUTTON))
  1023.                     AttachCxObj(YH->CxObj, tmp_obj);
  1024.             }
  1025.         }
  1026. #endif
  1027.     }
  1028. }
  1029.  
  1030.  
  1031. /* open/close resources needed for Mouse Cycling */
  1032. VOID
  1033. ToggleMouseCycling(VOID)
  1034.     UBYTE i;
  1035.  
  1036.     InitMouseCyclingPatterns();
  1037.  
  1038.     for (i=0; i< NUM_HANDLERS ; i++)
  1039.     {
  1040.         ToggleYakHandler(&MouseCyclingHandlers[i]);
  1041.     }
  1042. }
  1043.  
  1044.  
  1045. #endif
  1046.